using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Linq;

namespace NDK.NDKControl
{
	public class UserCurve : UserControl
	{
		private const int value_count_max = 2048;

		private float value_max_left = 100f;

		private float value_min_left = 0f;

		private float value_max_right = 100f;

		private float value_min_right = 0f;

		private int value_Segment = 5;

		private bool value_IsAbscissaStrech = false;

		private int value_StrechDataCountMax = 300;

		private bool value_IsRenderDashLine = true;

		private string textFormat = "HH:mm";

		private int value_IntervalAbscissaText = 100;

		private Random random = null;

		private string value_title = "";

		private int leftRight = 50;

		private int upDowm = 25;

		private Dictionary<string, HslCurveItem> data_list = null;

		private string[] data_text = null;

		private List<AuxiliaryLine> auxiliary_lines;

		private Font font_size9 = null;

		private Font font_size12 = null;

		private Brush brush_deep = null;

		private Pen pen_normal = null;

		private Pen pen_dash = null;

		private Color color_normal = Color.DeepPink;

		private Color color_deep = Color.DimGray;

		private Color color_dash = Color.Gray;

		private StringFormat format_left = null;

		private StringFormat format_right = null;

		private StringFormat format_center = null;

		private IContainer components = null;

		[Category("外观")]
		[Description("获取或设置图形的左纵坐标的最大值，该值必须大于最小值")]
		[Browsable(true)]
		[DefaultValue(100f)]
		public float ValueMaxLeft
		{
			get
			{
				return value_max_left;
			}
			set
			{
				if (value > value_min_left)
				{
					value_max_left = value;
					Invalidate();
				}
			}
		}

		[Category("外观")]
		[Description("获取或设置图形的左纵坐标的最小值，该值必须小于最大值")]
		[Browsable(true)]
		[DefaultValue(0f)]
		public float ValueMinLeft
		{
			get
			{
				return value_min_left;
			}
			set
			{
				if (value < value_max_left)
				{
					value_min_left = value;
					Invalidate();
				}
			}
		}

		[Category("外观")]
		[Description("获取或设置图形的右纵坐标的最大值，该值必须大于最小值")]
		[Browsable(true)]
		[DefaultValue(100f)]
		public float ValueMaxRight
		{
			get
			{
				return value_max_right;
			}
			set
			{
				if (value > value_min_right)
				{
					value_max_right = value;
					Invalidate();
				}
			}
		}

		[Category("外观")]
		[Description("获取或设置图形的右纵坐标的最小值，该值必须小于最大值")]
		[Browsable(true)]
		[DefaultValue(0f)]
		public float ValueMinRight
		{
			get
			{
				return value_min_right;
			}
			set
			{
				if (value < value_max_right)
				{
					value_min_right = value;
					Invalidate();
				}
			}
		}

		[Category("外观")]
		[Description("获取或设置图形的纵轴分段数")]
		[Browsable(true)]
		[DefaultValue(5)]
		public int ValueSegment
		{
			get
			{
				return value_Segment;
			}
			set
			{
				value_Segment = value;
				Invalidate();
			}
		}

		[Category("外观")]
		[Description("获取或设置所有的数据是否强制在一个界面里显示")]
		[Browsable(true)]
		[DefaultValue(false)]
		public bool IsAbscissaStrech
		{
			get
			{
				return value_IsAbscissaStrech;
			}
			set
			{
				value_IsAbscissaStrech = value;
				Invalidate();
			}
		}

		[Category("外观")]
		[Description("获取或设置拉伸模式下的最大数据量")]
		[Browsable(true)]
		[DefaultValue(300)]
		public int StrechDataCountMax
		{
			get
			{
				return value_StrechDataCountMax;
			}
			set
			{
				value_StrechDataCountMax = value;
				Invalidate();
			}
		}

		[Category("外观")]
		[Description("获取或设置虚线是否进行显示")]
		[Browsable(true)]
		[DefaultValue(true)]
		public bool IsRenderDashLine
		{
			get
			{
				return value_IsRenderDashLine;
			}
			set
			{
				value_IsRenderDashLine = value;
				Invalidate();
			}
		}

		[Category("外观")]
		[Description("获取或设置坐标轴及相关信息文本的颜色")]
		[Browsable(true)]
		[DefaultValue(typeof(Color), "DimGray")]
		public Color ColorLinesAndText
		{
			get
			{
				return color_deep;
			}
			set
			{
				color_deep = value;
				InitializationColor();
				Invalidate();
			}
		}

		[Category("外观")]
		[Description("获取或设置虚线的颜色")]
		[Browsable(true)]
		[DefaultValue(typeof(Color), "Gray")]
		public Color ColorDashLines
		{
			get
			{
				return color_dash;
			}
			set
			{
				color_dash = value;
				pen_dash?.Dispose();
				pen_dash = new Pen(color_dash);
				pen_dash.DashStyle = DashStyle.Custom;
				pen_dash.DashPattern = new float[2]
				{
					5f,
					5f
				};
				Invalidate();
			}
		}

		[Category("外观")]
		[Description("获取或设置纵向虚线的分隔情况，单位为多少个数据")]
		[Browsable(true)]
		[DefaultValue(100)]
		public int IntervalAbscissaText
		{
			get
			{
				return value_IntervalAbscissaText;
			}
			set
			{
				value_IntervalAbscissaText = value;
				Invalidate();
			}
		}

		[Category("外观")]
		[Description("获取或设置实时数据新增时文本相对应于时间的格式化字符串，默认HH:mm")]
		[Browsable(true)]
		[DefaultValue("HH:mm")]
		public string TextAddFormat
		{
			get
			{
				return textFormat;
			}
			set
			{
				textFormat = value;
				Invalidate();
			}
		}

		[Category("外观")]
		[Description("获取或设置图标的标题信息")]
		[Browsable(true)]
		[DefaultValue("")]
		public string Title
		{
			get
			{
				return value_title;
			}
			set
			{
				value_title = value;
				Invalidate();
			}
		}

		public UserCurve()
		{
			InitializeComponent();
			DoubleBuffered = true;
			random = new Random();
			data_list = new Dictionary<string, HslCurveItem>();
			auxiliary_lines = new List<AuxiliaryLine>();
			format_left = new StringFormat
			{
				LineAlignment = StringAlignment.Center,
				Alignment = StringAlignment.Near
			};
			format_right = new StringFormat
			{
				LineAlignment = StringAlignment.Center,
				Alignment = StringAlignment.Far
			};
			format_center = new StringFormat
			{
				LineAlignment = StringAlignment.Center,
				Alignment = StringAlignment.Center
			};
			font_size9 = new Font("宋体", 9f);
			font_size12 = new Font("宋体", 12f);
			InitializationColor();
			pen_dash = new Pen(color_deep);
			pen_dash.DashStyle = DashStyle.Custom;
			pen_dash.DashPattern = new float[2]
			{
				5f,
				5f
			};
		}

		private void InitializationColor()
		{
			pen_normal?.Dispose();
			brush_deep?.Dispose();
			pen_normal = new Pen(color_deep);
			brush_deep = new SolidBrush(color_deep);
		}

		public void SetCurveText(string[] descriptions)
		{
			data_text = descriptions;
			Invalidate();
		}

		public void SetLeftCurve(string key, float[] data)
		{
			SetLeftCurve(key, data, Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)));
		}

		public void SetLeftCurve(string key, float[] data, Color lineColor)
		{
			SetCurve(key, true, data, lineColor, 1f);
		}

		public void SetRightCurve(string key, float[] data)
		{
			SetRightCurve(key, data, Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)));
		}

		public void SetRightCurve(string key, float[] data, Color lineColor)
		{
			SetCurve(key, false, data, lineColor, 1f);
		}

		public void SetCurve(string key, bool isLeft, float[] data, Color lineColor, float thickness)
		{
			if (data_list.ContainsKey(key))
			{
				if (data == null)
				{
					data = new float[0];
				}
				data_list[key].Data = data;
			}
			else
			{
				if (data == null)
				{
					data = new float[0];
				}
				data_list.Add(key, new HslCurveItem
				{
					Data = data,
					LineThickness = thickness,
					LineColor = lineColor,
					IsLeftFrame = isLeft
				});
				if (data_text == null)
				{
					data_text = new string[data.Length];
				}
			}
			Invalidate();
		}

		public void RemoveCurve(string key)
		{
			if (data_list.ContainsKey(key))
			{
				data_list.Remove(key);
			}
			if (data_list.Count == 0)
			{
				data_text = new string[0];
			}
			Invalidate();
		}

		public void RemoveAllCurve()
		{
			int count = data_list.Count;
			data_list.Clear();
			if (data_list.Count == 0)
			{
				data_text = new string[0];
			}
			if (count > 0)
			{
				Invalidate();
			}
		}

		private void AddCurveData(string key, float[] values, bool isUpdateUI)
		{
			if ((values != null && values.Length < 1) || !data_list.ContainsKey(key))
			{
				return;
			}
			HslCurveItem hslCurveItem = data_list[key];
			if (hslCurveItem.Data != null)
			{
				if (value_IsAbscissaStrech)
				{
					SoftBasic.AddArrayData(ref hslCurveItem.Data, values, value_StrechDataCountMax);
				}
				else
				{
					SoftBasic.AddArrayData(ref hslCurveItem.Data, values, 2048);
				}
				if (isUpdateUI)
				{
					Invalidate();
				}
			}
		}

		private void AddCurveTime(int count)
		{
			if (data_text != null)
			{
				string[] array = new string[count];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = DateTime.Now.ToString(textFormat);
				}
				if (value_IsAbscissaStrech)
				{
					SoftBasic.AddArrayData(ref data_text, array, value_StrechDataCountMax);
				}
				else
				{
					SoftBasic.AddArrayData(ref data_text, array, 2048);
				}
			}
		}

		public void AddCurveData(string key, float value)
		{
			AddCurveData(key, new float[1]
			{
				value
			});
		}

		public void AddCurveData(string key, float[] values)
		{
			AddCurveData(key, values, false);
			if (values != null && values.Length != 0)
			{
				AddCurveTime(values.Length);
			}
			Invalidate();
		}

		public void AddCurveData(string[] keys, float[] values)
		{
			if (keys == null)
			{
				throw new ArgumentNullException("keys");
			}
			if (values == null)
			{
				throw new ArgumentNullException("values");
			}
			if (keys.Length != values.Length)
			{
				throw new Exception("两个参数的数组长度不一致。");
			}
			for (int i = 0; i < keys.Length; i++)
			{
				AddCurveData(keys[i], new float[1]
				{
					values[i]
				}, false);
			}
			AddCurveTime(1);
			Invalidate();
		}

		public void SetCurveVisible(string key, bool visible)
		{
			if (data_list.ContainsKey(key))
			{
				HslCurveItem hslCurveItem = data_list[key];
				hslCurveItem.Visible = visible;
				Invalidate();
			}
		}

		public void SetCurveVisible(string[] keys, bool visible)
		{
			foreach (string key in keys)
			{
				if (data_list.ContainsKey(key))
				{
					HslCurveItem hslCurveItem = data_list[key];
					hslCurveItem.Visible = visible;
				}
			}
			Invalidate();
		}

		public void AddLeftAuxiliary(float value)
		{
			AddLeftAuxiliary(value, ColorLinesAndText);
		}

		public void AddLeftAuxiliary(float value, Color lineColor)
		{
			AddLeftAuxiliary(value, lineColor, 1f);
		}

		public void AddLeftAuxiliary(float value, Color lineColor, float lineThickness)
		{
			AddAuxiliary(value, lineColor, lineThickness, true);
		}

		public void AddRightAuxiliary(float value)
		{
			AddRightAuxiliary(value, ColorLinesAndText);
		}

		public void AddRightAuxiliary(float value, Color lineColor)
		{
			AddRightAuxiliary(value, lineColor, 1f);
		}

		public void AddRightAuxiliary(float value, Color lineColor, float lineThickness)
		{
			AddAuxiliary(value, lineColor, lineThickness, false);
		}

		private void AddAuxiliary(float value, Color lineColor, float lineThickness, bool isLeft)
		{
			auxiliary_lines.Add(new AuxiliaryLine
			{
				Value = value,
				LineColor = lineColor,
				PenDash = new Pen(lineColor)
				{
					DashStyle = DashStyle.Custom,
					DashPattern = new float[2]
					{
						5f,
						5f
					}
				},
				IsLeftFrame = isLeft,
				LineThickness = lineThickness,
				LineTextBrush = new SolidBrush(lineColor)
			});
			Invalidate();
		}

		

		private void UserCurve_Paint(object sender, PaintEventArgs e)
		{
			Graphics graphics = e.Graphics;
			graphics.SmoothingMode = SmoothingMode.HighQuality;
			graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
			if (BackColor != Color.Transparent)
			{
				graphics.Clear(BackColor);
			}
			int width = Width;
			int height = Height;
			if (width < 120 || height < 60)
			{
				return;
			}
			graphics.DrawLines(pen_normal, new Point[4]
			{
				new Point(leftRight - 1, upDowm - 8),
				new Point(leftRight - 1, height - upDowm),
				new Point(width - leftRight, height - upDowm),
				new Point(width - leftRight, upDowm - 8)
			});
			if (!string.IsNullOrEmpty(value_title))
			{
				graphics.DrawString(value_title, font_size9, brush_deep, new Rectangle(0, 0, width - 1, 20), format_center);
			}
			SoftPainting.PaintTriangle(graphics, brush_deep, new Point(leftRight - 1, upDowm - 8), 4, GraphDirection.Upward);
			SoftPainting.PaintTriangle(graphics, brush_deep, new Point(width - leftRight, upDowm - 8), 4, GraphDirection.Upward);
			for (int i = 0; i < auxiliary_lines.Count; i++)
			{
				if (auxiliary_lines[i].IsLeftFrame)
				{
					auxiliary_lines[i].PaintValue = SoftPainting.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, auxiliary_lines[i].Value) + (float)upDowm;
				}
				else
				{
					auxiliary_lines[i].PaintValue = SoftPainting.ComputePaintLocationY(value_max_right, value_min_right, height - upDowm - upDowm, auxiliary_lines[i].Value) + (float)upDowm;
				}
			}
			for (int j = 0; j <= value_Segment; j++)
			{
				float value = (float)j * (value_max_left - value_min_left) / (float)value_Segment + value_min_left;
				float num = SoftPainting.ComputePaintLocationY(value_max_left, value_min_left, height - upDowm - upDowm, value) + (float)upDowm;
				if (IsNeedPaintDash(num))
				{
					graphics.DrawLine(pen_normal, leftRight - 4, num, leftRight - 1, num);
					RectangleF layoutRectangle = new RectangleF(0f, num - 9f, leftRight - 4, 20f);
					graphics.DrawString(value.ToString(), font_size9, brush_deep, layoutRectangle, format_right);
					float num2 = (float)j * (value_max_right - value_min_right) / (float)value_Segment + value_min_right;
					graphics.DrawLine(pen_normal, width - leftRight + 1, num, width - leftRight + 4, num);
					layoutRectangle.Location = new PointF(width - leftRight + 4, num - 9f);
					graphics.DrawString(num2.ToString(), font_size9, brush_deep, layoutRectangle, format_left);
					if (j > 0 && value_IsRenderDashLine)
					{
						graphics.DrawLine(pen_dash, leftRight, num, width - leftRight, num);
					}
				}
			}
			if (value_IsRenderDashLine)
			{
				if (value_IsAbscissaStrech)
				{
					float num3 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
					int num4 = CalculateDataCountByOffect(num3);
					for (int k = 0; k < value_StrechDataCountMax; k += num4)
					{
						if (k > 0 && k < value_StrechDataCountMax - 1)
						{
							graphics.DrawLine(pen_dash, (float)k * num3 + (float)leftRight, upDowm, (float)k * num3 + (float)leftRight, height - upDowm - 1);
						}
						if (data_text != null && k < data_text.Length && (float)k * num3 + (float)leftRight < (float)(data_text.Length - 1) * num3 + (float)leftRight - 40f)
						{
							graphics.DrawString(layoutRectangle: new Rectangle((int)((float)k * num3), height - upDowm + 1, 100, upDowm), s: data_text[k], font: font_size9, brush: brush_deep, format: format_center);
						}
					}
					string[] array = data_text;
					if (array != null && array.Length > 1)
					{
						if (data_text.Length < value_StrechDataCountMax)
						{
							graphics.DrawLine(pen_dash, (float)(data_text.Length - 1) * num3 + (float)leftRight, upDowm, (float)(data_text.Length - 1) * num3 + (float)leftRight, height - upDowm - 1);
						}
						graphics.DrawString(layoutRectangle: new Rectangle((int)((float)(data_text.Length - 1) * num3 + (float)leftRight) - leftRight, height - upDowm + 1, 100, upDowm), s: data_text[data_text.Length - 1], font: font_size9, brush: brush_deep, format: format_center);
					}
				}
				else
				{
					int num5 = width - 2 * leftRight + 1;
					for (int l = leftRight; l < width - leftRight; l += value_IntervalAbscissaText)
					{
						if (l != leftRight)
						{
							graphics.DrawLine(pen_dash, l, upDowm, l, height - upDowm - 1);
						}
						if (data_text == null)
						{
							continue;
						}
						int num6 = ((num5 > data_text.Length) ? data_text.Length : num5);
						if (l - leftRight < data_text.Length && num6 - (l - leftRight) > 40)
						{
							if (data_text.Length <= num5)
							{
								graphics.DrawString(layoutRectangle: new Rectangle(l - leftRight, height - upDowm + 1, 100, upDowm), s: data_text[l - leftRight], font: font_size9, brush: brush_deep, format: format_center);
								continue;
							}
							graphics.DrawString(layoutRectangle: new Rectangle(l - leftRight, height - upDowm + 1, 100, upDowm), s: data_text[l - leftRight + data_text.Length - num5], font: font_size9, brush: brush_deep, format: format_center);
						}
					}
					string[] array2 = data_text;
					if (array2 != null && array2.Length > 1)
					{
						if (data_text.Length >= num5)
						{
							graphics.DrawString(layoutRectangle: new Rectangle(width - leftRight - leftRight, height - upDowm + 1, 100, upDowm), s: data_text[data_text.Length - 1], font: font_size9, brush: brush_deep, format: format_center);
						}
						else
						{
							graphics.DrawLine(pen_dash, data_text.Length + leftRight - 1, upDowm, data_text.Length + leftRight - 1, height - upDowm - 1);
							graphics.DrawString(layoutRectangle: new Rectangle(data_text.Length + leftRight - 1 - leftRight, height - upDowm + 1, 100, upDowm), s: data_text[data_text.Length - 1], font: font_size9, brush: brush_deep, format: format_center);
						}
					}
				}
			}
			for (int m = 0; m < auxiliary_lines.Count; m++)
			{
				if (auxiliary_lines[m].IsLeftFrame)
				{
					graphics.DrawLine(auxiliary_lines[m].PenDash, leftRight - 4, auxiliary_lines[m].PaintValue, leftRight - 1, auxiliary_lines[m].PaintValue);
					graphics.DrawString(layoutRectangle: new RectangleF(0f, auxiliary_lines[m].PaintValue - 9f, leftRight - 4, 20f), s: auxiliary_lines[m].Value.ToString(), font: font_size9, brush: auxiliary_lines[m].LineTextBrush, format: format_right);
				}
				else
				{
					graphics.DrawLine(auxiliary_lines[m].PenDash, width - leftRight + 1, auxiliary_lines[m].PaintValue, width - leftRight + 4, auxiliary_lines[m].PaintValue);
					graphics.DrawString(layoutRectangle: new RectangleF(width - leftRight + 4, auxiliary_lines[m].PaintValue - 9f, leftRight - 4, 20f), s: auxiliary_lines[m].Value.ToString(), font: font_size9, brush: auxiliary_lines[m].LineTextBrush, format: format_left);
				}
				graphics.DrawLine(auxiliary_lines[m].PenDash, leftRight, auxiliary_lines[m].PaintValue, width - leftRight, auxiliary_lines[m].PaintValue);
			}
			if (value_IsAbscissaStrech)
			{
				foreach (HslCurveItem value2 in data_list.Values)
				{
					if (!value2.Visible)
					{
						continue;
					}
					float[] data = value2.Data;
					if (data != null && data.Length > 1)
					{
						float num7 = (float)(width - leftRight * 2) * 1f / (float)(value_StrechDataCountMax - 1);
						PointF[] array3 = new PointF[value2.Data.Length];
						for (int n = 0; n < value2.Data.Length; n++)
						{
							array3[n].X = (float)leftRight + (float)n * num7;
							array3[n].Y = SoftPainting.ComputePaintLocationY(value2.IsLeftFrame ? value_max_left : value_max_right, value2.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value2.Data[n]) + (float)upDowm;
						}
						using (Pen pen = new Pen(value2.LineColor, value2.LineThickness))
						{
							graphics.DrawLines(pen, array3);
						}
					}
				}
				return;
			}
			foreach (HslCurveItem value3 in data_list.Values)
			{
				if (!value3.Visible)
				{
					continue;
				}
				float[] data2 = value3.Data;
				if (data2 == null || data2.Length <= 1)
				{
					continue;
				}
				int num8 = width - 2 * leftRight + 1;
				PointF[] array4;
				if (value3.Data.Length <= num8)
				{
					array4 = new PointF[value3.Data.Length];
					for (int num9 = 0; num9 < value3.Data.Length; num9++)
					{
						array4[num9].X = leftRight + num9;
						array4[num9].Y = SoftPainting.ComputePaintLocationY(value3.IsLeftFrame ? value_max_left : value_max_right, value3.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value3.Data[num9]) + (float)upDowm;
					}
				}
				else
				{
					array4 = new PointF[num8];
					for (int num10 = 0; num10 < array4.Length; num10++)
					{
						array4[num10].X = leftRight + num10;
						array4[num10].Y = SoftPainting.ComputePaintLocationY(value3.IsLeftFrame ? value_max_left : value_max_right, value3.IsLeftFrame ? value_min_left : value_min_right, height - upDowm - upDowm, value3.Data[num10 + value3.Data.Length - num8]) + (float)upDowm;
					}
				}
				using (Pen pen2 = new Pen(value3.LineColor, value3.LineThickness))
				{
					graphics.DrawLines(pen2, array4);
				}
			}
		}

		private bool IsNeedPaintDash(float paintValue)
		{
			for (int i = 0; i < auxiliary_lines.Count; i++)
			{
				if (Math.Abs(auxiliary_lines[i].PaintValue - paintValue) < (float)font_size9.Height)
				{
					return false;
				}
			}
			return true;
		}

		private int CalculateDataCountByOffect(float offect)
		{
			if (offect > 40f)
			{
				return 1;
			}
			offect = 40f / offect;
			return (int)Math.Ceiling(offect);
		}

		private void UserCurve_SizeChanged(object sender, EventArgs e)
		{
			Invalidate();
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		private void InitializeComponent()
		{
			SuspendLayout();
            AutoScaleDimensions = new System.Drawing.SizeF(6f, 12f);
            AutoScaleMode = AutoScaleMode.Font;
			BackColor = Color.Transparent;
            Name = "UserCurve";
            Size = new System.Drawing.Size(615, 296);
            SizeChanged += new System.EventHandler(UserCurve_SizeChanged);
            Paint += new System.Windows.Forms.PaintEventHandler(UserCurve_Paint);
			ResumeLayout(false);
		}
	}

    internal class HslCurveItem
    {
        public float[] Data = null;

        public float LineThickness
        {
            get;
            set;
        }

        public Color LineColor
        {
            get;
            set;
        }

        public bool IsLeftFrame
        {
            get;
            set;
        }

        public bool Visible
        {
            get;
            set;
        }

        public HslCurveItem()
        {
            LineThickness = 1f;
            IsLeftFrame = true;
            Visible = true;
        }
    }

    internal class AuxiliaryLine : IDisposable
    {
        private bool disposedValue = false;

        public float Value
        {
            get;
            set;
        }

        public float PaintValue
        {
            get;
            set;
        }

        public Color LineColor
        {
            get;
            set;
        }

        public Pen PenDash
        {
            get;
            set;
        }

        public float LineThickness
        {
            get;
            set;
        }

        public Brush LineTextBrush
        {
            get;
            set;
        }

        public bool IsLeftFrame
        {
            get;
            set;
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    PenDash?.Dispose();
                    LineTextBrush.Dispose();
                }
                disposedValue = true;
            }
        }

        public void Dispose()
        {
            Dispose(true);
        }
    }

    public class SoftBasic
    {

        public static string CalculateFileMD5(string filePath)
        {
            string result = string.Empty;
            using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                result = CalculateStreamMD5(stream);
            }
            return result;
        }

        public static string CalculateStreamMD5(Stream stream)
        {
            byte[] value = null;
            using (MD5 mD = new MD5CryptoServiceProvider())
            {
                value = mD.ComputeHash(stream);
            }
            return BitConverter.ToString(value).Replace("-", "");
        }

        public static string CalculateStreamMD5(string data)
        {
            return CalculateStreamMD5(data, Encoding.UTF8);
        }

        public static string CalculateStreamMD5(string data, Encoding encode)
        {
            string result = string.Empty;
            using (MD5 mD = new MD5CryptoServiceProvider())
            {
                byte[] value = mD.ComputeHash(encode.GetBytes(data));
                result = BitConverter.ToString(value).Replace("-", "");
            }
            return result;
        }

        public static string CalculateStreamMD5(Bitmap bitmap)
        {
            MemoryStream memoryStream = new MemoryStream();
            bitmap.Save(memoryStream, bitmap.RawFormat);
            byte[] inBytes = null;
            using (MD5 mD = new MD5CryptoServiceProvider())
            {
                inBytes = mD.ComputeHash(memoryStream);
            }
            memoryStream.Dispose();
            return ByteToHexString(inBytes);
        }

        public static string GetSizeDescription(long size)
        {
            if (size < 1000)
            {
                return size + " B";
            }
            if (size < 1000000)
            {
                return ((float)size / 1024f).ToString("F2") + " Kb";
            }
            if (size < 1000000000)
            {
                return ((float)size / 1024f / 1024f).ToString("F2") + " Mb";
            }
            return ((float)size / 1024f / 1024f / 1024f).ToString("F2") + " Gb";
        }

   

        public static string ArrayFormat<T>(T[] array)
        {
            return ArrayFormat(array, string.Empty);
        }

        public static string ArrayFormat<T>(T[] array, string format)
        {
            if (array == null)
            {
                return "NULL";
            }
            StringBuilder stringBuilder = new StringBuilder("[");
            for (int i = 0; i < array.Length; i++)
            {
                stringBuilder.Append(string.IsNullOrEmpty(format) ? array[i].ToString() : string.Format(format, array[i]));
                if (i != array.Length - 1)
                {
                    stringBuilder.Append(",");
                }
            }
            stringBuilder.Append("]");
            return stringBuilder.ToString();
        }

        public static string ArrayFormat<T>(T array)
        {
            return ArrayFormat(array, string.Empty);
        }

        public static string ArrayFormat<T>(T array, string format)
        {
            StringBuilder stringBuilder = new StringBuilder("[");
            Array array2 = array as Array;
            if (array2 != null)
            {
                foreach (object item in array2)
                {
                    stringBuilder.Append(string.IsNullOrEmpty(format) ? item.ToString() : string.Format(format, item));
                    stringBuilder.Append(",");
                }
                if (array2.Length > 0 && stringBuilder[stringBuilder.Length - 1] == ',')
                {
                    stringBuilder.Remove(stringBuilder.Length - 1, 1);
                }
            }
            else
            {
                stringBuilder.Append(string.IsNullOrEmpty(format) ? array.ToString() : string.Format(format, array));
            }
            stringBuilder.Append("]");
            return stringBuilder.ToString();
        }

        public static void AddArrayData<T>(ref T[] array, T[] data, int max)
        {
            if (data == null || data.Length == 0)
            {
                return;
            }
            if (array.Length == max)
            {
                Array.Copy(array, data.Length, array, 0, array.Length - data.Length);
                Array.Copy(data, 0, array, array.Length - data.Length, data.Length);
            }
            else if (array.Length + data.Length > max)
            {
                T[] array2 = new T[max];
                for (int i = 0; i < max - data.Length; i++)
                {
                    array2[i] = array[i + (array.Length - max + data.Length)];
                }
                for (int j = 0; j < data.Length; j++)
                {
                    array2[array2.Length - data.Length + j] = data[j];
                }
                array = array2;
            }
            else
            {
                T[] array3 = new T[array.Length + data.Length];
                for (int k = 0; k < array.Length; k++)
                {
                    array3[k] = array[k];
                }
                for (int l = 0; l < data.Length; l++)
                {
                    array3[array3.Length - data.Length + l] = data[l];
                }
                array = array3;
            }
        }

        public static T[] ArrayExpandToLength<T>(T[] data, int length)
        {
            if (data == null)
            {
                return new T[length];
            }
            if (data.Length == length)
            {
                return data;
            }
            T[] array = new T[length];
            Array.Copy(data, array, Math.Min(data.Length, array.Length));
            return array;
        }

        public static T[] ArrayExpandToLengthEven<T>(T[] data)
        {
            if (data == null)
            {
                return new T[0];
            }
            if (data.Length % 2 == 1)
            {
                return ArrayExpandToLength(data, data.Length + 1);
            }
            return data;
        }

        public static List<T[]> ArraySplitByLength<T>(T[] array, int length)
        {
            if (array == null)
            {
                return new List<T[]>();
            }
            List<T[]> list = new List<T[]>();
            int num = 0;
            while (num < array.Length)
            {
                if (num + length < array.Length)
                {
                    T[] array2 = new T[length];
                    Array.Copy(array, num, array2, 0, length);
                    num += length;
                    list.Add(array2);
                }
                else
                {
                    T[] array3 = new T[array.Length - num];
                    Array.Copy(array, num, array3, 0, array3.Length);
                    num += length;
                    list.Add(array3);
                }
            }
            return list;
        }

        public static int[] SplitIntegerToArray(int integer, int everyLength)
        {
            int[] array = new int[integer / everyLength + ((integer % everyLength != 0) ? 1 : 0)];
            for (int i = 0; i < array.Length; i++)
            {
                if (i == array.Length - 1)
                {
                    array[i] = ((integer % everyLength == 0) ? everyLength : (integer % everyLength));
                }
                else
                {
                    array[i] = everyLength;
                }
            }
            return array;
        }

        public static bool IsTwoBytesEquel(byte[] b1, int start1, byte[] b2, int start2, int length)
        {
            if (b1 == null || b2 == null)
            {
                return false;
            }
            for (int i = 0; i < length; i++)
            {
                if (b1[i + start1] != b2[i + start2])
                {
                    return false;
                }
            }
            return true;
        }

        public static bool IsTwoBytesEquel(byte[] b1, byte[] b2)
        {
            if (b1 == null || b2 == null)
            {
                return false;
            }
            if (b1.Length != b2.Length)
            {
                return false;
            }
            return IsTwoBytesEquel(b1, 0, b2, 0, b1.Length);
        }

        public static bool IsByteTokenEquel(byte[] head, Guid token)
        {
            return IsTwoBytesEquel(head, 12, token.ToByteArray(), 0, 16);
        }

        public static bool IsTwoTokenEquel(Guid token1, Guid token2)
        {
            return IsTwoBytesEquel(token1.ToByteArray(), 0, token2.ToByteArray(), 0, 16);
        }

        public static TEnum[] GetEnumValues<TEnum>() where TEnum : struct
        {
            return (TEnum[])Enum.GetValues(typeof(TEnum));
        }

        public static TEnum GetEnumFromString<TEnum>(string value) where TEnum : struct
        {
            return (TEnum)Enum.Parse(typeof(TEnum), value);
        }

  

     

        public static void ShowExceptionMessage(Exception ex)
        {
            MessageBox.Show(GetExceptionMessage(ex));
        }

        public static void ShowExceptionMessage(string extraMsg, Exception ex)
        {
            MessageBox.Show(GetExceptionMessage(extraMsg, ex));
        }

        public static string GetExceptionMessage(Exception ex)
        {
            return "";
        }

        public static string GetExceptionMessage(string extraMsg, Exception ex)
        {
            if (string.IsNullOrEmpty(extraMsg))
            {
                return GetExceptionMessage(ex);
            }
            return extraMsg + Environment.NewLine + GetExceptionMessage(ex);
        }

        public static string ByteToHexString(byte[] InBytes)
        {
            return ByteToHexString(InBytes, '\0');
        }

        public static string ByteToHexString(byte[] InBytes, char segment)
        {
            return ByteToHexString(InBytes, segment, 0);
        }

        public static string ByteToHexString(byte[] InBytes, char segment, int newLineCount)
        {
            if (InBytes == null)
            {
                return string.Empty;
            }
            StringBuilder stringBuilder = new StringBuilder();
            long num = 0L;
            foreach (byte b in InBytes)
            {
                if (segment == '\0')
                {
                    stringBuilder.Append($"{b:X2}");
                }
                else
                {
                    stringBuilder.Append($"{b:X2}{segment}");
                }
                num++;
                if (newLineCount > 0 && num >= newLineCount)
                {
                    stringBuilder.Append(Environment.NewLine);
                    num = 0L;
                }
            }
            if (segment != 0 && stringBuilder.Length > 1 && stringBuilder[stringBuilder.Length - 1] == segment)
            {
                stringBuilder.Remove(stringBuilder.Length - 1, 1);
            }
            return stringBuilder.ToString();
        }

        public static string ByteToHexString(string InString)
        {
            return ByteToHexString(Encoding.Unicode.GetBytes(InString));
        }

        private static int GetHexCharIndex(char ch)
        {
            switch (ch)
            {
                case '0':
                    return 0;
                case '1':
                    return 1;
                case '2':
                    return 2;
                case '3':
                    return 3;
                case '4':
                    return 4;
                case '5':
                    return 5;
                case '6':
                    return 6;
                case '7':
                    return 7;
                case '8':
                    return 8;
                case '9':
                    return 9;
                case 'A':
                case 'a':
                    return 10;
                case 'B':
                case 'b':
                    return 11;
                case 'C':
                case 'c':
                    return 12;
                case 'D':
                case 'd':
                    return 13;
                case 'E':
                case 'e':
                    return 14;
                case 'F':
                case 'f':
                    return 15;
                default:
                    return -1;
            }
        }

        public static byte[] HexStringToBytes(string hex)
        {
            MemoryStream memoryStream = new MemoryStream();
            for (int i = 0; i < hex.Length; i++)
            {
                if (i + 1 < hex.Length && GetHexCharIndex(hex[i]) >= 0 && GetHexCharIndex(hex[i + 1]) >= 0)
                {
                    memoryStream.WriteByte((byte)(GetHexCharIndex(hex[i]) * 16 + GetHexCharIndex(hex[i + 1])));
                    i++;
                }
            }
            byte[] result = memoryStream.ToArray();
            memoryStream.Dispose();
            return result;
        }

      

        public static byte[] BytesToAsciiBytes(byte[] inBytes)
        {
            return Encoding.ASCII.GetBytes(ByteToHexString(inBytes));
        }

        public static byte[] AsciiBytesToBytes(byte[] inBytes)
        {
            return HexStringToBytes(Encoding.ASCII.GetString(inBytes));
        }

        public static byte[] BuildAsciiBytesFrom(byte value)
        {
            return Encoding.ASCII.GetBytes(value.ToString("X2"));
        }

        public static byte[] BuildAsciiBytesFrom(short value)
        {
            return Encoding.ASCII.GetBytes(value.ToString("X4"));
        }

        public static byte[] BuildAsciiBytesFrom(ushort value)
        {
            return Encoding.ASCII.GetBytes(value.ToString("X4"));
        }

        public static byte[] BuildAsciiBytesFrom(byte[] value)
        {
            byte[] array = new byte[value.Length * 2];
            for (int i = 0; i < value.Length; i++)
            {
                BuildAsciiBytesFrom(value[i]).CopyTo(array, 2 * i);
            }
            return array;
        }

        private static byte GetDataByBitIndex(int offset)
        {
            switch (offset)
            {
                case 0:
                    return 1;
                case 1:
                    return 2;
                case 2:
                    return 4;
                case 3:
                    return 8;
                case 4:
                    return 16;
                case 5:
                    return 32;
                case 6:
                    return 64;
                case 7:
                    return 128;
                default:
                    return 0;
            }
        }

        public static bool BoolOnByteIndex(byte value, int offset)
        {
            byte dataByBitIndex = GetDataByBitIndex(offset);
            return (value & dataByBitIndex) == dataByBitIndex;
        }

        public static byte[] BoolArrayToByte(bool[] array)
        {
            if (array == null)
            {
                return null;
            }
            int num = ((array.Length % 8 == 0) ? (array.Length / 8) : (array.Length / 8 + 1));
            byte[] array2 = new byte[num];
            for (int i = 0; i < array.Length; i++)
            {
                if (array[i])
                {
                    array2[i / 8] += GetDataByBitIndex(i % 8);
                }
            }
            return array2;
        }

        public static bool[] ByteToBoolArray(byte[] InBytes, int length)
        {
            if (InBytes == null)
            {
                return null;
            }
            if (length > InBytes.Length * 8)
            {
                length = InBytes.Length * 8;
            }
            bool[] array = new bool[length];
            for (int i = 0; i < length; i++)
            {
                array[i] = BoolOnByteIndex(InBytes[i / 8], i % 8);
            }
            return array;
        }

        public static bool[] ByteToBoolArray(byte[] InBytes)
        {
            return (InBytes == null) ? null : ByteToBoolArray(InBytes, InBytes.Length * 8);
        }

        public static T[] ArrayRemoveDouble<T>(T[] value, int leftLength, int rightLength)
        {
            if (value == null)
            {
                return null;
            }
            if (value.Length <= leftLength + rightLength)
            {
                return new T[0];
            }
            T[] array = new T[value.Length - leftLength - rightLength];
            Array.Copy(value, leftLength, array, 0, array.Length);
            return array;
        }

        public static T[] ArrayRemoveBegin<T>(T[] value, int length)
        {
            return ArrayRemoveDouble(value, length, 0);
        }

        public static T[] ArrayRemoveLast<T>(T[] value, int length)
        {
            return ArrayRemoveDouble(value, 0, length);
        }

        public static T[] ArraySelectMiddle<T>(T[] value, int index, int length)
        {
            if (value == null)
            {
                return null;
            }
            T[] array = new T[Math.Min(value.Length, length)];
            Array.Copy(value, index, array, 0, array.Length);
            return array;
        }

        public static T[] ArraySelectBegin<T>(T[] value, int length)
        {
            T[] array = new T[Math.Min(value.Length, length)];
            if (array.Length != 0)
            {
                Array.Copy(value, 0, array, 0, array.Length);
            }
            return array;
        }

        public static T[] ArraySelectLast<T>(T[] value, int length)
        {
            T[] array = new T[Math.Min(value.Length, length)];
            Array.Copy(value, value.Length - length, array, 0, array.Length);
            return array;
        }

        public static byte[] SpliceTwoByteArray(byte[] bytes1, byte[] bytes2)
        {
            if (bytes1 == null && bytes2 == null)
            {
                return null;
            }
            if (bytes1 == null)
            {
                return bytes2;
            }
            if (bytes2 == null)
            {
                return bytes1;
            }
            byte[] array = new byte[bytes1.Length + bytes2.Length];
            bytes1.CopyTo(array, 0);
            bytes2.CopyTo(array, bytes1.Length);
            return array;
        }

        public static byte[] SpliceByteArray(params byte[][] bytes)
        {
            int num = 0;
            for (int i = 0; i < bytes.Length; i++)
            {
                byte[] obj = bytes[i];
                if (obj != null && obj.Length != 0)
                {
                    num += bytes[i].Length;
                }
            }
            int num2 = 0;
            byte[] array = new byte[num];
            for (int j = 0; j < bytes.Length; j++)
            {
                byte[] obj2 = bytes[j];
                if (obj2 != null && obj2.Length != 0)
                {
                    bytes[j].CopyTo(array, num2);
                    num2 += bytes[j].Length;
                }
            }
            return array;
        }

        public static string[] SpliceStringArray(string first, string[] array)
        {
            List<string> list = new List<string>();
            list.Add(first);
            list.AddRange(array);
            return list.ToArray();
        }

        public static string[] SpliceStringArray(string first, string second, string[] array)
        {
            List<string> list = new List<string>();
            list.Add(first);
            list.Add(second);
            list.AddRange(array);
            return list.ToArray();
        }

        public static string[] SpliceStringArray(string first, string second, string third, string[] array)
        {
            List<string> list = new List<string>();
            list.Add(first);
            list.Add(second);
            list.Add(third);
            list.AddRange(array);
            return list.ToArray();
        }

        public static object DeepClone(object oringinal)
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter
                {
                    Context = new StreamingContext(StreamingContextStates.Clone)
                };
                binaryFormatter.Serialize(memoryStream, oringinal);
                memoryStream.Position = 0L;
                return binaryFormatter.Deserialize(memoryStream);
            }
        }

        public static string GetUniqueStringByGuidAndRandom()
        {
            Random random = new Random();
            return Guid.NewGuid().ToString("N") + random.Next(1000, 10000);
        }
    }

    public static class SoftPainting
    {
        public static Bitmap GetGraphicFromArray(int[] array, int width, int height, int degree, Color lineColor)
        {
            if (width < 10 && height < 10)
            {
                throw new ArgumentException("长宽不能小于等于10");
            }
            int max = array.Max();
            int min = 0;
            int num = array.Length;
            StringFormat stringFormat = new StringFormat();
            stringFormat.Alignment = StringAlignment.Far;
            Pen pen = new Pen(Color.LightGray, 1f);
            pen.DashStyle = DashStyle.Custom;
            pen.DashPattern = new float[2]
            {
                5f,
                5f
            };
            Font font = new Font("宋体", 9f);
            Bitmap bitmap = new Bitmap(width, height);
            Graphics graphics = Graphics.FromImage(bitmap);
            graphics.SmoothingMode = SmoothingMode.AntiAlias;
            graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
            graphics.Clear(Color.White);
            int num2 = 60;
            int num3 = 8;
            int num4 = 8;
            int num5 = 8;
            int num6 = width - num2 - num3;
            int num7 = height - num4 - num5;
            Rectangle rectangle = new Rectangle(num2 - 1, num4 - 1, num6 + 1, num7 + 1);
            graphics.DrawLine(Pens.Gray, num2 - 1, num4, num2 + num6 + 1, num4);
            graphics.DrawLine(Pens.Gray, num2 - 1, num4 + num7 + 1, num2 + num6 + 1, num4 + num7 + 1);
            graphics.DrawLine(Pens.Gray, num2 - 1, num4 - 1, num2 - 1, num4 + num7 + 1);
            PaintCoordinateDivide(graphics, Pens.DimGray, pen, font, Brushes.DimGray, stringFormat, degree, max, min, width, height, num2, num3, num4, num5);
            PointF[] array2 = new PointF[array.Length];
            for (int i = 0; i < array.Length; i++)
            {
                array2[i].X = (float)num6 * 1f / (float)(array.Length - 1) * (float)i + (float)num2;
                array2[i].Y = ComputePaintLocationY(max, min, num7, array[i]) + (float)num4 + 1f;
            }
            Pen pen2 = new Pen(lineColor);
            graphics.DrawLines(pen2, array2);
            pen2.Dispose();
            pen.Dispose();
            font.Dispose();
            stringFormat.Dispose();
            graphics.Dispose();
            return bitmap;
        }

        public static float ComputePaintLocationY(int max, int min, int height, int value)
        {
            return (float)height - (float)(value - min) * 1f / (float)(max - min) * (float)height;
        }

        public static float ComputePaintLocationY(float max, float min, int height, float value)
        {
            return (float)height - (value - min) / (max - min) * (float)height;
        }

        public static void PaintCoordinateDivide(Graphics g, Pen penLine, Pen penDash, Font font, Brush brush, StringFormat sf, int degree, int max, int min, int width, int height, int left = 60, int right = 8, int up = 8, int down = 8)
        {
            for (int i = 0; i <= degree; i++)
            {
                int value = (max - min) * i / degree + min;
                int num = (int)ComputePaintLocationY(max, min, height - up - down, value) + up + 1;
                g.DrawLine(penLine, left - 1, num, left - 4, num);
                if (i != 0)
                {
                    g.DrawLine(penDash, left, num, width - right, num);
                }
                g.DrawString(value.ToString(), font, brush, new Rectangle(-5, num - font.Height / 2, left, font.Height), sf);
            }
        }

        public static void PaintTriangle(Graphics g, Brush brush, Point point, int size, GraphDirection direction)
        {
            Point[] array = new Point[4];
            switch (direction)
            {
                case GraphDirection.Ledtward:
                    array[0] = new Point(point.X, point.Y - size);
                    array[1] = new Point(point.X, point.Y + size);
                    array[2] = new Point(point.X - 2 * size, point.Y);
                    break;
                case GraphDirection.Rightward:
                    array[0] = new Point(point.X, point.Y - size);
                    array[1] = new Point(point.X, point.Y + size);
                    array[2] = new Point(point.X + 2 * size, point.Y);
                    break;
                case GraphDirection.Upward:
                    array[0] = new Point(point.X - size, point.Y);
                    array[1] = new Point(point.X + size, point.Y);
                    array[2] = new Point(point.X, point.Y - 2 * size);
                    break;
                default:
                    array[0] = new Point(point.X - size, point.Y);
                    array[1] = new Point(point.X + size, point.Y);
                    array[2] = new Point(point.X, point.Y + 2 * size);
                    break;
            }
            array[3] = array[0];
            g.FillPolygon(brush, array);
        }

        public static Bitmap GetGraphicFromArray(Paintdata[] array, int width, int height, GraphicRender graphic)
        {
            if (width < 10 && height < 10)
            {
                throw new ArgumentException("长宽不能小于等于10");
            }
            array.Max((Paintdata m) => m.Count);
            Action<Paintdata[], GraphicRender, Graphics> action = delegate
            {
            };
            return null;
        }

       
    }

    public enum GraphDirection
    {
        Upward = 1,
        Downward,
        Ledtward,
        Rightward
    }

    public enum GraphicRender
    {
        Histogram = 1,
        Piechart,
        Linegraph
    }

    public struct Paintdata
    {
        public int Count
        {
            get;
            set;
        }

        public string Description
        {
            get;
            set;
        }
    }
}
